home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / uupc11ys.zip / MAIL / MLIB.C < prev    next >
C/C++ Source or Header  |  1993-04-10  |  13KB  |  424 lines

  1. /*
  2.    ibmpc/mlib.c   by <skl@van-bc.UUCP>   August/87
  3.  
  4.  
  5.    Mailer UA system-dependent library
  6.  
  7.    Services to provide in mlib.c:
  8.  
  9.    Get a single character from the console.
  10.    Invoke the local editor on a given file.
  11.    Determine if a given file stream points to the console.
  12.    Get a line from the console.
  13.    Invoke a local pager on a given file.
  14.  
  15.    Update history:
  16.  
  17.    13 May 89      Use PC format path names for editor                   ahd
  18.    01 Oct 89      Make Console_fgets use far pointers
  19.                   Alter Console_fgets and Is_Console to type boolean
  20.                                                                         ahd
  21.    29 Jul 90      Use PC format path names for pager                    ahd
  22. */
  23.  
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <conio.h>
  28. #include <io.h>
  29. #include <dos.h>
  30.  
  31. #ifdef WIN32
  32. #include <windows.h>
  33. #endif
  34.  
  35. #include "lib.h"
  36. #include "hlib.h"
  37.  
  38. #ifdef FAMILYAPI
  39. #define SIMPLE_CONSOLE_FGETS
  40. #endif
  41.  
  42. #ifdef WIN32
  43. #define SIMPLE_CONSOLE_FGETS
  44. #endif
  45.  
  46. #ifndef SIMPLE_CONSOLE_FGETS
  47. #define MULTIPLEX 0x2f        /* 8086 DOS Interrupt for multiplexing */
  48.  
  49. static int DOSRead( char *buff, const int buflen);
  50.  
  51. static boolean DOSKeyActive( void );
  52.  
  53. static int DOSKeyRead( char *buff , int buflen );
  54.  
  55. #endif
  56.  
  57.  
  58. /*
  59.    G e t _ O n e
  60.  
  61.    Get a single character from the console
  62. */
  63.  
  64. int Get_One()
  65. {
  66.  
  67.    return getch();
  68.  
  69. } /*Get_One*/
  70.  
  71.  
  72. /*
  73.    I n v o k e _ E d i t o r
  74.  
  75.    Invoke the user's editor to edit a text file
  76. */
  77.  
  78. int Invoke_Editor(const char *ecmd, const char *filename)
  79. {
  80.    char command[FILENAME_MAX*2 + 1];
  81.    char tempname[FILENAME_MAX];                          /* ahd   */
  82.    int  column = 0;                                      /* ahd   */
  83.  
  84.    if (ecmd == nil(char)) {
  85.       printf("Invoke_Editor: No editor specified.\n");
  86.       return 1;
  87.    }
  88.  
  89.    puts("\nInvoking editor ...\n");
  90.  
  91.    strcpy(tempname,filename);                            /* ahd   */
  92.  
  93.    while (tempname[column] != '\0') {                    /* ahd   */
  94.       if (tempname[column] ==  '/')                      /* ahd   */
  95.          tempname[column] = '\\';                        /* ahd   */
  96.       column = column + 1;                               /* ahd   */
  97.   }                                                      /* ahd   */
  98.  
  99.  
  100.    sprintf(command, ecmd, tempname);                     /* ahd   */
  101.    if (system(command) != 0) {
  102.       printf("Invoke_Editor: system(\"%s\") failed.\n", command);
  103.       return 2;
  104.    }
  105.  
  106.    return 0;
  107.  
  108. } /*Invoke_Editor*/
  109.  
  110.  
  111. /*
  112.    Is_Console - is this stream from the console?
  113.  
  114.    Note: isatty actually returns if the stream is a character device,
  115.          thus causing device NUL to appear interactive; this is not
  116.          acceptable, but I don't know a trivial fix.           ahd
  117. */
  118.  
  119. boolean Is_Console(FILE *stream)                                  /* ahd   */
  120. {
  121.  
  122.    return isatty(fileno(stream));
  123.  
  124. } /*Is_Console*/
  125.  
  126.  
  127. /*
  128.    Console_fgets - get a line of input from the local console
  129.  
  130.    This is a hook to allow for using the local system's facility
  131.    for input line editing.  We call DOS to perform a line read,
  132.    thus allowing utilities like DOSEDIT or CED to do their fancy work.
  133. */
  134.  
  135. #ifndef SIMPLE_CONSOLE_FGETS
  136.  
  137. boolean Console_fgets(char *buff, int buflen, char *prompt)
  138. {
  139.    static boolean eof = FALSE;    /* pending EOF flag  */
  140.  
  141.    char *eofptr;
  142.  
  143.    if (eof) {           /* have a pending EOF?  */
  144.       eof = FALSE;      /* no more pending EOF  */
  145.       return FALSE;     /* signal the EOF    */
  146.    }
  147.  
  148. /*--------------------------------------------------------------------*/
  149. /*      Prompt the user, read the data, and then go to a new line     */
  150. /*--------------------------------------------------------------------*/
  151.  
  152.    fputs(prompt, stdout);
  153.  
  154.    if ( DOSKeyActive() )
  155.       buflen = DOSKeyRead( buff, buflen );
  156.    else
  157.       buflen = DOSRead( buff, buflen );
  158.     putchar('\n');
  159.  
  160. /*--------------------------------------------------------------------*/
  161. /*             Determine if we hit end of file on the read            */
  162. /*--------------------------------------------------------------------*/
  163.  
  164.    if ( buflen == -1 )
  165.    {
  166.       *buff = '\0';
  167.       return FALSE;
  168.    }
  169.  
  170. /*--------------------------------------------------------------------*/
  171. /*                        Terminate the buffer                        */
  172. /*--------------------------------------------------------------------*/
  173.  
  174.    buff[buflen] = '\n';
  175.    buff[buflen + 1] = '\0';
  176.  
  177.    if ((eofptr = strchr(buff, '\x1a')) == nil(char))
  178.       return TRUE;      /* an ordinary successful read   */
  179.    else if (eofptr == buff)
  180.    {
  181.       return FALSE;     /* signal EOF right away      */
  182.    }
  183.    else {
  184.       eof = TRUE;       /* we now have a pending EOF  */
  185.       *eofptr = '\0';
  186.       return TRUE;      /* read successful but EOF next  */
  187.    } /* else */
  188.  
  189. } /*Console_fgets*/
  190.  
  191. /*--------------------------------------------------------------------*/
  192. /*    D O S R e a d                                                   */
  193. /*                                                                    */
  194. /*    Read from console under DOS without DOSKEY                      */
  195. /*--------------------------------------------------------------------*/
  196.  
  197. static int DOSRead( char *buff, const int buflen)
  198. {
  199.    union REGS regs;
  200.    struct SREGS sregs;
  201.  
  202.    struct {
  203.       unsigned char maximum, actual;
  204.       char buffer[255];
  205.    } request;
  206.  
  207.    char far *p = (char far *) &request;
  208.  
  209. /*--------------------------------------------------------------------*/
  210. /*            Set up the address of our read buffer for DOS           */
  211. /*--------------------------------------------------------------------*/
  212.  
  213.    sregs.ds = FP_SEG( p );    /* Use segment of the buffer           */
  214.    regs.x.dx = (unsigned int)(&request);
  215.    request.maximum = (unsigned char) min( buflen - 1,
  216.                                           sizeof request.buffer);
  217.    regs.h.ah = 0x0a;          /* Buffered keyboard input             */
  218.  
  219. /*--------------------------------------------------------------------*/
  220. /*                  Invoke the buffered console read                  */
  221. /*--------------------------------------------------------------------*/
  222.  
  223.    intdosx(®s, ®s, &sregs);
  224.  
  225. /*--------------------------------------------------------------------*/
  226. /*                        Now return the result                       */
  227. /*--------------------------------------------------------------------*/
  228.  
  229.    memcpy( buff, request.buffer, request.actual );
  230.    return (unsigned int) request.actual;
  231.  
  232. } /* DOSRead */
  233.  
  234. /*--------------------------------------------------------------------*/
  235. /*    D O S K e y A c t i v e                                         */
  236. /*                                                                    */
  237. /*    Determine if the DOS Key command line editor is active          */
  238. /*--------------------------------------------------------------------*/
  239.  
  240. static boolean DOSKeyActive( void )
  241. {
  242.    static boolean first_pass = TRUE;
  243.    static boolean active = FALSE;
  244.  
  245.    if ( first_pass )
  246.    {
  247.       first_pass = FALSE;
  248.       if ((_osmajor > 4) )
  249.       {
  250.          union REGS regs;
  251.  
  252. #ifdef __TURBOC__
  253.          if ( getvect( MULTIPLEX ) == NULL )
  254. #else
  255.          if ( _dos_getvect( MULTIPLEX ) == NULL )
  256. #endif
  257.             printmsg(0,"Multiplex interrupt not installed???\n");
  258.          else {
  259.             regs.x.ax = 0x4800;     /* Request for DOS Key active */
  260.             int86( MULTIPLEX , ®s, ®s );
  261.             if ( regs.h.al != 0x00 )
  262.                active = TRUE;
  263.          }
  264.       } /* if (_osmajor > 4 ) */
  265.    } /* if ( first_pass ) */
  266.  
  267. /*--------------------------------------------------------------------*/
  268. /*                          Return to caller                          */
  269. /*--------------------------------------------------------------------*/
  270.  
  271.    if ( bflag[F_DOSKEY] && ! active )
  272.    {
  273.      printmsg(0,"DOSKEY support not enabled, option disabled");
  274.      bflag[F_DOSKEY] = FALSE;
  275.    }
  276.  
  277.    return bflag[F_DOSKEY] && active;
  278.  
  279. } /* DOSKeyActive */
  280.  
  281.  
  282. /*--------------------------------------------------------------------*/
  283. /*    D O S K e y R e a d                                             */
  284. /*                                                                    */
  285. /*    Read a line from the terminal using DOS Key                     */
  286. /*--------------------------------------------------------------------*/
  287.  
  288. static int DOSKeyRead( char *buff , int buflen )
  289. {
  290.    union REGS regs;
  291.    struct SREGS sregs;
  292.  
  293.    struct {
  294.       unsigned char maximum, actual;
  295.       char buffer[126];
  296.    } request;
  297.  
  298.    char far *p = (char far *) &request;
  299.  
  300. /*--------------------------------------------------------------------*/
  301. /*                   Set up for the DOSKEY read call                  */
  302. /*--------------------------------------------------------------------*/
  303.  
  304.    sregs.ds = FP_SEG( p );    /* Use segment of the buffer           */
  305.    regs.x.dx = (unsigned int)(&request);
  306.    regs.x.ax = 0x4810;
  307.    request.maximum = (unsigned char) min( buflen - 1, sizeof request );
  308.  
  309. /*--------------------------------------------------------------------*/
  310. /*                      Issue the call to DOSKEY                      */
  311. /*--------------------------------------------------------------------*/
  312.  
  313.    int86x( MULTIPLEX, ®s, ®s, &sregs );
  314.  
  315. /*--------------------------------------------------------------------*/
  316. /*                          Check the result                          */
  317. /*--------------------------------------------------------------------*/
  318.  
  319.    if ( regs.x.ax == 0 )      /* Function succeed?                */
  320.    {
  321.       buflen = request.actual;
  322.       memcpy( buff, request.buffer , buflen );
  323.    } /* if ( regs.x.ax == 0 ) */
  324.    else {                        /* Function failed, report it    */
  325.       printmsg(0,"DOSKEY read failed!");
  326.       buflen = -1;
  327.    } /* else */
  328.  
  329. /*--------------------------------------------------------------------*/
  330. /*                          Return to caller                          */
  331. /*--------------------------------------------------------------------*/
  332.  
  333.    return buflen;
  334.  
  335. } /* DOSKeyRead */
  336.  
  337. #else
  338.  
  339. boolean Console_fgets(char *buff, int buflen, char *prompt)
  340. {
  341.  
  342.    if (bflag[F_DOSKEY] )
  343.    {
  344.      printmsg(0,"DOSKEY support not available, option disabled");
  345.      bflag[F_DOSKEY] = FALSE;
  346.    }
  347.  
  348.    fputs(prompt, stdout);
  349.  
  350.    return (fgets(buff, buflen, stdin) != nil(char)) ? TRUE : FALSE;
  351.  
  352. } /*Console_fgets*/
  353.  
  354. #endif
  355.  
  356.  
  357. /*
  358.    L _ i n v o k e _ p a g e r
  359.  
  360.    Invoke the user's pager to view a text file
  361. */
  362.  
  363. int L_invoke_pager(const char *pcmd, const char *filename)
  364. {
  365.    char command[FILENAME_MAX*2 + 1];
  366.    char tempname[FILENAME_MAX];                          /* ahd   */
  367.    int  column = 0;                                      /* ahd   */
  368.  
  369.    if (pcmd == nil(char)) {
  370.       printf("L_invoke_pager: No pager specified.\n");
  371.       return 1;
  372.    }
  373.  
  374.    strcpy(tempname,filename);                            /* ahd   */
  375.  
  376.    while (tempname[column] != '\0') {                    /* ahd   */
  377.       if (tempname[column] ==  '/')                      /* ahd   */
  378.          tempname[column] = '\\';                        /* ahd   */
  379.       column += 1;                                       /* ahd   */
  380.   }                                                      /* ahd   */
  381.  
  382.    sprintf(command, pcmd, tempname);
  383.    if (system(command) != 0) {
  384.       printf("L_invoke_pager: system(\"%s\") failed.\n", command);
  385.       return 2;
  386.    }
  387.  
  388.    return 0;
  389.  
  390. } /*L_invoke_pager*/
  391.  
  392. /*
  393.       C l e a r
  394.  
  395.       Clear the screen
  396.  */
  397. void ClearScreen()
  398. {
  399. #ifdef WIN32
  400.    long    mode;
  401.    static COORD    coord = {0, 0};
  402.    static HANDLE cons_hnd = INVALID_HANDLE_VALUE;
  403. #endif
  404.  
  405. #ifdef __TURBOC__                                           /* pdm */
  406.       clrscr();                                             /* ahd */
  407. #else                                                       /* pdm */
  408. #ifdef WIN32                                                /* ebr */
  409.  
  410.    if (cons_hnd == INVALID_HANDLE_VALUE) {
  411.       cons_hnd = GetStdHandle(STD_OUTPUT_HANDLE);
  412.       GetConsoleMode(cons_hnd, &mode);
  413.       mode |= ENABLE_PROCESSED_OUTPUT;
  414.       SetConsoleMode(cons_hnd, mode);
  415.    }
  416.    SetConsoleCursorPosition(cons_hnd, coord);
  417.    FillConsoleOutputCharacter(cons_hnd, 0x20, 60*132, coord, &mode);
  418.  
  419. #else
  420.       fputs("\033[2J", stdout);     /* ANSI Erase screen       ahd */
  421. #endif /* WIN32 */                                          /* pdm */
  422. #endif /* __TURBOC__ */
  423. }
  424.